package com.kingstar.ceres.data.remote.sftp;

import com.jcraft.jsch.*;
import com.kingstar.ceres.data.remote.ConnectionConfig;
import com.kingstar.ceres.data.remote.ConnectionWrapper;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

@Slf4j
public class SftpConnection implements ConnectionWrapper {
    private final ThreadLocal<ChannelSftp> channelLocal=new ThreadLocal<>();
    private final ThreadLocal<Session> sessionLocal=new ThreadLocal<>();

    @Setter
    private ConnectionConfig.SftpConfig config;

    @Override
    public boolean connection() {
        JSch jSch = new JSch();
        try {
            log.info("连接远程服务器:{}",config);
            Session session = jSch.getSession(config.getUsername(), config.getHost(), config.getPort());
            setIfNotEmpty(config.getPassword(),session::setPassword);
            setIfNotEmpty("StrictHostKeyChecking",config.getStrictHostKeyChecking(),session::setConfig);
            setIfNotEmpty("PreferredAuthentications",config.getPreferredAuthentications(),session::setConfig);
            if(StringUtils.isNotBlank(config.getPrvkey())){
                session.setPassword(config.getUsername());
                jSch.addIdentity(config.getPrvkey());
                jSch.setKnownHosts(config.getKnownHosts());
            }
            session.connect(10000);
            Channel sftp = session.openChannel("sftp");
            sftp.connect(10000);
            ChannelSftp channel=(ChannelSftp)sftp;
            sessionLocal.set(session);
            channelLocal.set(channel);
            return true;
        } catch (Exception e) {
            log.error("连接远程服务器异常:{}",config,e);
            return false;
        }
    }

    @Override
    public void close() {
        final ChannelSftp channelSftp = channelLocal.get();
        final Session session = sessionLocal.get();
        try {
            if (channelSftp!=null){
                channelLocal.remove();
                channelSftp.exit();
            }
            if (session!=null){
                sessionLocal.remove();
                session.disconnect();
            }
            log.info("safe close the connect");
        } catch (Exception e) {
            log.info("close the connect failed",e);
        }
    }

    @Override
    public boolean upload(String srcPath,String dstPath) {
        try {
            log.info("上传文件,src:{},dst:{}",srcPath,dstPath);
            String dstDir=dstPath.substring(0,dstPath.lastIndexOf(config.getRemoteSplitChar()));
            if(!isExist(dstDir)){
                channelLocal.get().mkdir(dstDir);
            }
            channelLocal.get().put(srcPath,dstPath);
            log.info("文件上传成功,src:{},dst:{}",srcPath,dstPath);
            return true;
        } catch (SftpException e) {
            log.error("文件上传失败,src:{},dst:{}",srcPath,dstPath,e);
            return false;
        }
    }

    public boolean isExist(String path){
        boolean  isExist=false;
        try {
            channelLocal.get().lstat(path);
            isExist = true;
        } catch (Exception e) {
            if (e.getMessage().toLowerCase().equals("no such file")) {
                isExist = false;
            }
            log.warn("file do not exist:{}",path);
        }
        return isExist;
    }

    @Override
    public String buildRemotePath(String dir, String filename) {
        return dir+config.getRemoteSplitChar()+filename;
    }

    @Override
    public boolean download(String srcPath,String dstPath) {
        try {
            log.info("下载文件,src:{},dst:{}",srcPath,dstPath);
            channelLocal.get().get(srcPath,dstPath);
            log.info("文件下载成功,src:{},dst:{}",srcPath,dstPath);
            return true;
        } catch (SftpException e) {
            log.error("文件下载失败,src:{},dst:{}",srcPath,dstPath,e);
            return false;
        }
    }
}
